package com.bluexmicro.module_componment.file

import android.os.Environment
import androidx.lifecycle.*
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import java.io.File
import java.io.FileFilter
import java.io.Serializable
import java.math.BigInteger

class FileViewModel : ViewModel() {

    //只是选择的文件
    val selectedFile = MutableStateFlow<File?>(null)
    private val _data = MutableStateFlow(FolderModel())
    val data: StateFlow<FolderModel> = _data

    private val _result = MutableSharedFlow<FileResult>()
    val result: SharedFlow<FileResult> = _result

    private val _backEvent = MutableSharedFlow<Boolean>()

    /**
     * 因为这里拦截了返回事件
     */
    val backEvent: SharedFlow<Boolean> = _backEvent

    fun choose(file: File, address: BigInteger?) {
        viewModelScope.launch {
            _result.emit(FileResult(file, address))
        }
    }

    fun onBackEvent() {
        viewModelScope.launch {
            _backEvent.emit(true)
        }
    }

    /**
     * 回到上一级
     */
    fun loadParent(): Boolean {
        val data = _data.value
        return if (data.folderStacks.size <= 1) {
            false
        } else {
            val currentFolderIndex = data.folderStacks.lastIndex - 1
            val currentFolder = data.folderStacks[currentFolderIndex]
            _data.update {
                it.loadFolder(currentFolder)
            }
            true
        }
    }

    fun loadFolder(file: File) {
        if (file != root && file.isFile) return
        _data.update {
            it.loadFolder(file)
        }
    }

    ///////////////////////////////////////////////////////////////////////////
    //
    ///////////////////////////////////////////////////////////////////////////

    private val _withAddress = MutableStateFlow(false)
    private val _payload = MutableStateFlow("")
    val withAddress: StateFlow<Boolean> = _withAddress
    val payload: StateFlow<String> = _payload
    private var addressPayload = StringBuffer()

    fun appendNumber(num: String) {
        if (num.length > 1) return
        //todo is(0,1,2,3,4,5,6,7,8,9,A,B,C,D,F)
        if (addressPayload.length < 8) {
            addressPayload.append(num)
            _payload.value = addressPayload.toString()
        }
    }

    fun backspace() {
        if (addressPayload.isNotEmpty()) {
            addressPayload.deleteCharAt(addressPayload.lastIndex)
            _payload.value = addressPayload.toString()
        }
    }

    fun setWithAddress(with: Boolean) {
        _withAddress.value = with
        addressPayload = StringBuffer()
        _payload.value = ""
    }

}

val root = File("root")
val fileFilter: FileFilter = FileFilter {
    val extensions = mutableListOf("bin", "BIN")
    if (it.isHidden || it.startsWith(".")) {
        return@FileFilter false
    }
    if (it.isDirectory) {
        return@FileFilter true
    }
    return@FileFilter extensions.contains(it.extension)
}

class FolderModel {


    private val externalDir: File
        get() = Environment.getExternalStorageDirectory()

    var folderStacks: List<File> = listOf(root)//这里要控制不能为空
    var currentFiles: List<File> = listOf(externalDir)


    /**
     * @return 如果发生变化返回新的FolderModel对象，否则是旧对象
     */
    fun loadFolder(file: File): FolderModel {
        if (folderStacks.isNotEmpty() && file == folderStacks.last()) return this//已是当前目录了，保持不变
        folderStacks = if (file == root) {
            //这不是一个正常的file，所以这里特殊处理
            listOf(root)
        } else {
            if (file.isFile) return this
            val index = folderStacks.indexOf(file)
            if (index >= 0) {
                folderStacks.subList(0, index + 1)
            } else {
                val newList = folderStacks.toMutableList()
                newList.add(file)
                newList
            }
        }
        if (folderStacks.isEmpty()) {
            //这里应为不可能事件
            folderStacks = listOf(root)
        }
        val currentFolder = folderStacks.last()
        currentFiles = if (currentFolder == root) {
            listOf(externalDir)
        } else {
            currentFolder.listFiles(fileFilter)?.asList()?.sortedBy {
                it.nameWithoutExtension
            }?.sortedBy {
                it.isFile
            } ?: emptyList()
        }
        return this.clone()
    }

    private fun clone(): FolderModel {
        return FolderModel().also {
            it.folderStacks = folderStacks
            it.currentFiles = currentFiles
        }
    }

}

data class FileResult(
    val file: File,
    val address: BigInteger?
) : Serializable


